#include "ABSBondInfo.h"

#include <core/Utility.h>
#include <string.h>

#include <vector>

#include "QBIssuerInfo.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#ifdef _DEBUG
// #define	new	DEBUG_NEW
#endif
namespace {
const std::vector<std::string> g_sBaseType = {
    "全部",         "汽车贷款",   "消费贷款",   "小微/小额", "汽车融资租赁",
    "其他融资租赁", "地产供应链", "其他供应链", "应收账款",  "保理融资",
    "CMBS",         "类REITS",    "NPL",        "特定非金",  "RMBS",
    "并表ABS/ABN",  "购房尾款",   "基础设施",   "其他"};
const std::vector<std::string> g_sBaseTypeShow = {
    "全部",        "汽车贷款", "消费贷款", "小微/小额", "融资租赁",
    "融资租赁",    "供应链",   "供应链",   "应收账款",  "保理融资",
    "CMBS",        "类REITS",  "NPL",      "特定非金",  "RMBS",
    "并表ABS/ABN", "购房尾款", "基础设施", "其他"};
const std::vector<std::string> g_sTrancheClassFirst = {
    "A",   "A1", "A-1", "A1-1", "A1-2", "A2",  "A-2",   "A3",
    "A-3", "A4", "A-4", "A5",   "AA",   "AAA", "SENIOR"};
const std::vector<std::string> g_sTrancheClassSecond = {"B", "C", "D"};
const char g_sTrancheClassSub[] = "SUB";
}  // namespace

CABSBondInfo::CABSBondInfo() { Clear(); }

CABSBondInfo::CABSBondInfo(const CABSBondInfo& one) {
  Clear();
  FIELDCOPY(m_sBondKey, one.m_sBondKey);
  FIELDCOPY(m_sABSID, one.m_sABSID);
  FIELDCOPY(m_sSeriesName, one.m_sSeriesName);
  FIELDCOPY(m_sIssuerCode, one.m_sIssuerCode);
  FIELDCOPY(m_sType1, one.m_sType1);
  FIELDCOPY(m_sType2, one.m_sType2);
  FIELDCOPY(m_sType3, one.m_sType3);
  FIELDCOPY(m_sActualFinancier, one.m_sActualFinancier);
  FIELDCOPY(m_sCreditSubject, one.m_sCreditSubject);
  m_nBaseType = one.m_nBaseType;
  m_nTrancheClass = one.m_nTrancheClass;
}

CABSBondInfo::~CABSBondInfo() {}

const char* CABSBondInfo::GetBaseTypeString(int nType) {
  if (nType < BASETYPE_ALL || nType >= BASETYPE_NUM) return "";
  return g_sBaseType[nType].c_str();
}

void CABSBondInfo::Clear() {
  memset(m_sBondKey, 0, sizeof(m_sBondKey));
  memset(m_sABSID, 0, sizeof(m_sABSID));
  memset(m_sSeriesName, 0, sizeof(m_sSeriesName));
  memset(m_sIssuerCode, 0, sizeof(m_sIssuerCode));
  memset(m_sType1, 0, sizeof(m_sType1));
  memset(m_sType2, 0, sizeof(m_sType2));
  memset(m_sType3, 0, sizeof(m_sType3));
  memset(m_sActualFinancier, 0, sizeof(m_sActualFinancier));
  memset(m_sCreditSubject, 0, sizeof(m_sCreditSubject));
  m_nBaseType = BASETYPE_NONE;
  m_nTrancheClass = TRANCHE_NONE;
}

void CABSBondInfo::SetBondKey(const char* sBondKey) {
  memset(m_sBondKey, 0, sizeof(m_sBondKey));
  if (NULL == sBondKey) return;
  FIELDCOPY(m_sBondKey, sBondKey);
}
void CABSBondInfo::SetABSID(const char* sABSID) {
  memset(m_sABSID, 0, sizeof(m_sABSID));
  if (NULL == sABSID) return;
  FIELDCOPY(m_sABSID, sABSID);
}
void CABSBondInfo::SetSeriesName(const char* sSeriesName) {
  memset(m_sSeriesName, 0, sizeof(m_sSeriesName));
  if (NULL == sSeriesName) return;
  FIELDCOPY(m_sSeriesName, sSeriesName);
}
void CABSBondInfo::SetIssuerCode(const char* sIssuerCode) {
  memset(m_sIssuerCode, 0, sizeof(m_sIssuerCode));
  if (NULL == sIssuerCode) return;
  FIELDCOPY(m_sIssuerCode, sIssuerCode);
}
void CABSBondInfo::SetABSType(const char* sType1, const char* sType2,
                              const char* sType3) {
  memset(m_sType1, 0, sizeof(m_sType1));
  memset(m_sType2, 0, sizeof(m_sType2));
  memset(m_sType3, 0, sizeof(m_sType3));
  m_nBaseType = BASETYPE_NONE;

  FIELDCOPY(m_sType1, sType1);
  FIELDCOPY(m_sType2, sType2);
  FIELDCOPY(m_sType3, sType3);

  if (strcmp(m_sType2, "个人汽车贷款") == 0) {
    m_nBaseType = BASETYPE_CARAUTO;
  } else if (strcmp(m_sType2, "个人消费金融") == 0 ||
             strcmp(m_sType2, "个人消费贷款") == 0)
    m_nBaseType = BASETYPE_CONSUMER;
  else if (strcmp(m_sType2, "小微贷款") == 0 ||
           strcmp(m_sType2, "小额贷款") == 0 ||
           strcmp(m_sType2, "微小企业贷款") == 0)
    m_nBaseType = BASETYPE_MICRO;
  else if (strcmp(m_sType2, "融资租赁") == 0 &&
           strcmp(m_sType3, "汽车融资租赁") == 0)
    m_nBaseType = BASETYPE_CARLEASE;
  else if (strcmp(m_sType2, "融资租赁") == 0 &&
           strcmp(m_sType3, "汽车融资租赁") != 0)
    m_nBaseType = BASETYPE_OTHERLEASE;
  else if (strcmp(m_sType2, "供应链") == 0 &&
           strcmp(m_sType3, "地产供应链") == 0)
    m_nBaseType = BASETYPE_PROPERTYSUM;
  else if (strcmp(m_sType2, "供应链") == 0 &&
           strcmp(m_sType3, "地产供应链") != 0)
    m_nBaseType = BASETYPE_OTHERSUM;
  else if (strcmp(m_sType2, "应收账款") == 0)
    m_nBaseType = BASETYPE_ACCOUNTSRECEIVABLE;
  else if (strcmp(m_sType2, "保理融资") == 0)
    m_nBaseType = BASETYPE_TRADEFIN;
  else if (strcmp(m_sType2, "CMBS/CMBN") == 0)
    m_nBaseType = BASETYPE_CMBS;
  else if (strcmp(m_sType2, "类Reits") == 0)
    m_nBaseType = BASETYPE_REITS;
  else if (strcmp(m_sType2, "不良资产重组") == 0)
    m_nBaseType = BASETYPE_NPL;
  else if (strcmp(m_sType2, "特定非金债权") == 0)
    m_nBaseType = BASETYPE_SPECIFICNONGOLD;
  else if (strcmp(m_sType2, "住房抵押贷款") == 0)
    m_nBaseType = BASETYPE_RMBS;
  else if (strcmp(m_sType2, "有限合伙份额") == 0)
    m_nBaseType = BASETYPE_ABSABN;
  else if (strcmp(m_sType2, "购房尾款") == 0)
    m_nBaseType = BASETYPE_BALANCE;
  else if (strcmp(m_sType2, "基础设施收费收益权") == 0)
    m_nBaseType = BASETYPE_ACCOUNTS;
  else
    m_nBaseType = BASETYPE_OTHER;
}

void CABSBondInfo::SetAcutulFinancier(const char* sAcutulFinancier) {
  memset(m_sActualFinancier, 0, sizeof(m_sActualFinancier));
  if (NULL == sAcutulFinancier) return;
  FIELDCOPY(m_sActualFinancier, sAcutulFinancier);
}
void CABSBondInfo::SetCreditSubject(const char* sCreditSubject) {
  memset(m_sCreditSubject, 0, sizeof(m_sCreditSubject));
  if (NULL == sCreditSubject) return;
  FIELDCOPY(m_sCreditSubject, sCreditSubject);
}
void CABSBondInfo::SetTrancheClass(const char* sTrancheClass) {
  m_nTrancheClass = TRANCHE_NONE;
  if (NULL == sTrancheClass) return;
  if (strcmp(sTrancheClass, "优先") == 0)
    m_nTrancheClass = TRANCHE_FISRT;
  else if (strcmp(sTrancheClass, "夹层") == 0)
    m_nTrancheClass = TRANCHE_SECOND;
  else if (strcmp(sTrancheClass, "劣后") == 0)
    m_nTrancheClass = TRANCHE_SUB;
}

const char* CABSBondInfo::GetBondKey() { return m_sBondKey; }
const char* CABSBondInfo::GetABSID() const { return m_sABSID; }
const char* CABSBondInfo::GetBaseTypeString() const {
  if (m_nBaseType <= BASETYPE_ALL || m_nBaseType >= BASETYPE_NUM) return "";
  if (m_nBaseType == BASETYPE_OTHER) {
    return m_sType2;
  }
  return g_sBaseTypeShow[m_nBaseType].c_str();
}
const char* CABSBondInfo::GetSeriesName() const { return m_sSeriesName; }
const char* CABSBondInfo::GetIssuerCode() const { return m_sIssuerCode; }
const char* CABSBondInfo::GetABSType1() const { return m_sType1; }
const char* CABSBondInfo::GetABSType2() const { return m_sType2; }
const char* CABSBondInfo::GetABSType3() const { return m_sType3; }
const char* CABSBondInfo::GetAcutulFinancier() const {
  return m_sActualFinancier;
}
const char* CABSBondInfo::GetCreditSubject() const { return m_sCreditSubject; }
int CABSBondInfo::GetTrancheClass() const { return m_nTrancheClass; }

bool CABSBondInfo::CheckBaseType(const BLHCONDITION& Cond) const {
  for (int i = 0; i < 20; i++) {
    if (Cond.nABSBaseType[i] == m_nBaseType) return true;
  }
  return false;
}

bool CABSBondInfo::CheckTrancheClass(const BLHCONDITION& Cond) const {
  for (int i = 0; i < 10; i++) {
    if (Cond.nABSTrancheClass[i] == TRANCHE_ALL) break;
    if (Cond.nABSTrancheClass[i] == m_nTrancheClass) return true;
  }
  return false;
}

bool CABSBondInfo::CheckSeries(const BLHCONDITION& Cond) const {
  CQBIssuerInfo& iinfo = CQBIssuerInfo::ABSBondSeries();
  for (int i = 0; i < 200; i++) {
    if (Cond.szABSSeries[i][0] == '\0') return false;
    const IssuerInfo* pI = iinfo.GetIssuerInfo(Cond.szABSSeries[i]);
    if (pI &&
        strcmp(m_sSeriesName, pI->field((int)kIssuerInfo::Full_Name_C)) == 0)
      return true;
  }
  return false;
}

bool CABSBondInfo::CheckIssuer(const BLHCONDITION& Cond) const {
  for (int i = 0; i < BLH_ISSUERCOUNT; i++) {
    if (Cond.szABSIssuer[i][0] == '\0') return false;
    if (strcmp(m_sIssuerCode, Cond.szABSIssuer[i]) == 0) return true;
  }
  return false;
}

bool CABSBondInfo::CheckAcutulFinancier(const BLHCONDITION& Cond) const {
  for (int i = 0; i < BLH_ISSUERCOUNT; i++) {
    if (Cond.szABSFinancier[i][0] == '\0') return false;
    if (strstr(m_sActualFinancier, Cond.szABSFinancier[i]) != NULL) return true;
  }
  return false;
}